package com.carter.springframework.beans.factory.support;

import com.carter.springframework.beans.exception.BeanException;
import com.carter.springframework.beans.factory.FactoryBean;
import com.carter.springframework.beans.factory.config.DefaultSingletonBeanRegistry;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>();

    protected Object getCachedObjectForFactoryBean(String beanName) {
        Object obj = factoryBeanObjectCache.get(beanName);
        return obj;
    }

    protected Object getObjectFromFactoryBean(FactoryBean<?> factoryBean,String beanName){
        if (factoryBean.isSingleton()){
            Object obj = getCachedObjectForFactoryBean(beanName);
            if (obj==null){
                obj = doGetObjectFromFactoryBean(factoryBean,beanName);
                factoryBeanObjectCache.put(beanName,obj==null?NULL_OBJECT:obj);
            }
            return obj==NULL_OBJECT?null:obj;
        }else {
            return doGetObjectFromFactoryBean(factoryBean,beanName);
        }
    }

    private Object doGetObjectFromFactoryBean(FactoryBean<?> factoryBean,String beanName){
        try{
            return factoryBean.getObject();
        }catch (Exception e){
            throw new BeanException("factory bean threw exception on object [" + beanName + "] creation.");
        }
    }
}
